/**
 * 维护敏感消息预警规则列表
 */
import { type OptionalFields, Service } from '@gnlab/utils'
import type { Services } from '@/services'
import { API } from '@/services/common/api'

export enum WarnRuleType {
  Exact = 0, // 精确匹配
  Fuzzy = 1, // 包含匹配
  Regex = 2, // 正则匹配
  Delay = 3, // 超时未回复
}

interface BaseWarnRule {
  id: number
  name: string
  enable: boolean
  isGlobal: boolean
}
export interface GeneralWarnRule extends BaseWarnRule {
  type: Exclude<WarnRuleType, WarnRuleType.Delay>
  content: string
}
export interface DelayWarnRule extends BaseWarnRule {
  type: WarnRuleType.Delay
  content: DelayConfig
}
export interface DelayConfig {
  timeout: number // 多久不回复视为超时（单位：分钟）
  newOnly: boolean // 此配置是否只对“新好友前 N 条消息”生效
  newLimit: number // 此配置对新好友的前“多少”条消息生效（需 newOnly 为 true 才生效）
}
export type WarnRule = GeneralWarnRule | DelayWarnRule

// DelayConfig 中字段的默认值
export const DEFAULT_DELAY_TIMEOUT = 1
export const DEFAULT_DELAY_NEW_LIMIT = 10

interface RespWarnRule {
  Id: number
  RuleName: string // 规则名称
  RuleType: WarnRuleType // 规则类型
  RuleContent: string // 规则内容
  Enable: boolean // 是否启用
  Type: 0 | 1 // 0 全局  1 个人
}

function formatWarnRule(raw: RespWarnRule): WarnRule {
  const base = {
    id: raw.Id,
    name: raw.RuleName,
    enable: raw.Enable,
    isGlobal: raw.Type === 0,
  }
  const type = raw.RuleType
  if (type === WarnRuleType.Delay) {
    const [rawTimeout = '', rawNewLimit = ''] = raw.RuleContent.split('|')
    const timeout = isFinite(parseInt(rawTimeout, 10))
      ? parseInt(rawTimeout, 10)
      : DEFAULT_DELAY_TIMEOUT
    const [newOnly, newLimit] =
      rawNewLimit && isFinite(parseInt(rawNewLimit, 10))
        ? [true, parseInt(rawNewLimit, 10)]
        : [false, DEFAULT_DELAY_NEW_LIMIT]
    return { ...base, type, content: { timeout, newOnly, newLimit } }
  } else {
    return { ...base, type, content: raw.RuleContent }
  }
}

function makeRespWarnRule(
  rule: OptionalFields<WarnRule, 'id'>,
): OptionalFields<RespWarnRule, 'Id'> {
  return {
    Id: rule.id,
    RuleName: rule.name,
    RuleType: rule.type,
    RuleContent:
      rule.type === WarnRuleType.Delay
        ? combineDelayConfig(rule.content as DelayConfig)
        : (rule.content as string),
    Enable: rule.enable,
    Type: rule.isGlobal ? 0 : 1,
  }
}

export function combineDelayConfig(content: DelayConfig) {
  return content.newOnly ? `${content.timeout}|${content.newLimit}` : content.timeout.toString()
}

export class SensitiveWarns extends Service<Services> {
  private get auth() {
    return this.services.auth
  }

  async load() {
    return API('/Config/GetSensitiveWarnConfig', {
      formatter: (raw: RespWarnRule[]) => {
        const isAdmin = this.auth.isAdmin$.value
        return raw.map(formatWarnRule).filter(rule => {
          if (isAdmin !== true && rule.isGlobal && !rule.enable) return false
          return true
        })
      },
    })
  }

  async addOrUpdate(rule: OptionalFields<WarnRule, 'id'>) {
    return API('/Config/SaveSensitiveWarnConfig', {
      data: makeRespWarnRule(rule),
      formatter() {},
    })
  }

  async remove(id: number) {
    return API('/Config/RemoveSensitiveWarnConfig', {
      data: { Id: id },
      formatter() {},
    })
  }
}
